/**
 *
 * 多选（矢量多选）
 * @param     viewer          Mars3d实例对象
 * 
 * @function  rectangle       框选
 * @function  polygon         多边形选择
 * @function  circle          圈选
 * @function  clear           清除选择
 */


export function BQGIS_initMultiple (viewer) {
    return new BQGIS_multiple(viewer)
}

function BQGIS_multiple (viewer = window.viewer) {
    this.viewer = viewer
    this.selectGraphic = []
    this.select3Dtiles = []
    this.graphicLayer = new mars3d.layer.GraphicLayer()
    this.viewer.addLayer(this.graphicLayer)
    this.event = null
}


// BQGIS_multiple.prototype.
BQGIS_multiple.prototype.clear = function (callBack = () => {}) {
  if(this.event){
    this.event()
  }
  this.select3Dtiles.forEach(item => {
    item.feature.color = Cesium.Color.clone(new Cesium.Color(), item.feature.color)
  })
  this.graphicLayer.clear()
  callBack(this.selectGraphic, this.select3Dtiles)
  this.selectGraphic = []
  this.select3Dtiles = []
}

BQGIS_multiple.prototype.polygon = function (callBack = () => {}) {
  this.clear()
  this.graphicLayer.startDraw({
    type: "polygon",
    style: {
      color: "#ffff00",
      opacity: 0.2,
      clampToGround: true
    },
    success: (graphic) => {
      this.selectGraphicLayer(graphic, callBack)
      this.select3DtilesLayer(graphic, callBack)
    }
  })
}

BQGIS_multiple.prototype.circle = function (callBack = () => {}) {
  this.clear()
  this.graphicLayer.startDraw({
    type: "circle",
    style: {
      color: "#ffff00",
      opacity: 0.2,
      clampToGround: true
    },
    success: (graphic) => {
      this.selectGraphicLayer(graphic, callBack)
      this.select3DtilesLayer(graphic, callBack)
    }
  })
}

BQGIS_multiple.prototype.rectangle = function (callBack = () => {}) {
    this.clear()
    this.graphicLayer.startDraw({
      type: "rectangle",
      style: {
        color: "#ffff00",
        opacity: 0.2,
        clampToGround: true
      },
      success: (graphic) => {
        this.selectGraphicLayer(graphic, callBack)
        this.select3DtilesLayer(graphic, callBack)
      }
    })
}


BQGIS_multiple.prototype.selectGraphicLayer = function(graphic, callBack) {
  this.viewer.entities.values.forEach(element => {
    const position = element.position.getValue()
    const isInArea = graphic.isInPoly(position)
    if (isInArea) {
      const data = {
        id: element.id,
        name: element.name
      }
      this.selectGraphic.push({ 
        data,
        graphic: element
      })
      callBack(data, element, 'graphic')
    }
  });
}

BQGIS_multiple.prototype.select3DtilesLayer = function (graphic, callBack, tiles3dLayer) {
  const primitives = this.viewer.scene.primitives
  primitives._primitives.forEach(tileset => {
    if(tileset instanceof Cesium.Cesium3DTileset){
        const isChecked = this.isInArea(graphic, tileset.boundingSphere)
        if(isChecked){
          this.event = tileset.tileLoad.addEventListener((tile) => {
            const each = (tile) => {
              if(tile.children && tile.children.length){
                tile.children.forEach(item => {
                  each(item)
                })
              }else{
                const isCheckedTile = this.isInArea(graphic, tile.boundingSphere)
                if(isCheckedTile){
                  const content = tile.content
                  if(!content) return
                  const featuresLength = content.featuresLength
                  for (let i = 0; i < featuresLength; ++i) {
                    const feature = content.getFeature(i)
                    const keys = feature.getPropertyNames()
                    const data = {}
                    keys.forEach(key => {
                        data[key] = feature.getProperty(key)
                    })
                    let originColor = new Cesium.Color()
                    Cesium.Color.clone(feature.color, originColor)
                    this.select3Dtiles.push({
                      data,
                      feature,
                      originColor
                    })
                    callBack(data, feature, '3dtile')
                    feature.color = Cesium.Color.clone(Cesium.Color.YELLOW, feature.color)
                  }
                }
              }
            }
            each(tile)
          })
      }
    }
  })
}

BQGIS_multiple.prototype.isInArea = function (graphic, boundingSphere){
  let isChecked = false

  if(graphic.isInPoly(boundingSphere.center)){
    return true
  }else if(graphic.type === "circle"){
    const radius = graphic.radius + boundingSphere.radius
    const distance = Cesium.Cartesian3.distance(graphic.center, boundingSphere.center)
    return radius > distance
  }else if(graphic.type === "polygon"){
    const positions = graphic.positions.getValue().positions
    const distance = Cesium.Cartesian3.distance(graphic.center, boundingSphere.center)
    for(let i = 0; i < positions.length - 1; i++){
      const d = this.getDistanceByPointToLine(boundingSphere.center, positions[i], positions[i + 1])
      if(d < boundingSphere.radius){
        return true
      }
    }
  }
}

BQGIS_multiple.prototype.getDistanceByPointToLine = function(point, pnt1, pnt2) {
  var dis = 0;
  if (pnt1.x == pnt2.x) {
      if (pnt1.y == pnt2.y) {
          var dx = point.x - pnt1.x;
          var dy = point.y - pnt1.y;
          dis = Math.sqrt(dx * dx + dy * dy);
      } else
          dis = Math.abs(point.x - pnt1.x);
  } else {
      var lineK = (pnt2.y - pnt1.y) / (pnt2.x - pnt1.x);
      var lineC = (pnt2.x * pnt1.y - pnt1.x * pnt2.y) / (pnt2.x - pnt1.x);
      dis = Math.abs(lineK * point.x - point.y + lineC) / (Math.sqrt(lineK * lineK + 1));
  }
  return dis;
}